package com.hntx.joymusic.sytRetrofity;


import android.util.Log;

import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.hntx.joymusic.Constants;

import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

public class SytRetrofitBase {
    private static Retrofit mRetrofit;
    private static Retrofit mRetrofitJianQ;
    private static Retrofit mRetrofitNewJQ;
    private static Retrofit mRetrofitQR;

    static X509TrustManager trustManager;
    static SSLSocketFactory sslSocketFactory;

    public static void setCer(InputStream cerIn) {
        //读取自签名证书
        try {
            //通过trustManagerForCertificates方法为证书生成 TrustManager
            trustManager = trustManagerForCertificates(cerIn);
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{trustManager}, null);
            sslSocketFactory = sslContext.getSocketFactory();
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        }
    }

    private static KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
        try {
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            InputStream in = null;
            // 传入 'null' 会生成一个空的 Keytore
            //password 用于检查 KeyStore 完整性和 KeyStore 解锁
            keyStore.load(in, password);
            return keyStore;
        } catch (IOException e) {
            throw new AssertionError(e);
        }
    }

    public static X509TrustManager trustManagerForCertificates(InputStream in) throws GeneralSecurityException {
        //InputStream 可以包含多个证书

        //CertificateFactory 用于生成 Certificate，也就是数字证书
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        //由输入流生成证书
        Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
        if (certificates.isEmpty()) {
            throw new IllegalArgumentException("expected non-empty set of trusted certificates");
        }

        // 将证书放入 keyStore
        char[] password = "password".toCharArray(); // "password"可以任意设置
        KeyStore keyStore = newEmptyKeyStore(password);
        int index = 0;
        for (Certificate certificate : certificates) {
            String certificateAlias = Integer.toString(index++);
            keyStore.setCertificateEntry(certificateAlias, certificate);
        }

        // 用　KeyStore 生成 X509 trust manager.
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
                KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, password);
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
                TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(keyStore);
        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
        if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
            throw new IllegalStateException("Unexpected default trust managers:"
                    + Arrays.toString(trustManagers));
        }
        return (X509TrustManager) trustManagers[0];
    }

    //日志显示级别。
    static HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.HEADERS;

    //http拦截器。
    static HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
        @Override
        public void log(String message) {
            Log.d("sssss", message);
        }
    });


    static Interceptor interceptor = chain -> {
//        String reu = chain.request().body().toString();
//        Log.d("TAGsss", "request:" + reu);
//        Log.d("TAGsss", "request:");
        return chain.proceed(chain
                .request()
                .newBuilder()
                .build());
    };
    static OkHttpClient okHttpClient = null;
    static OkHttpClient.Builder okHttpClientyunup = null;

    private static OkHttpClient ok() {
        loggingInterceptor.setLevel(level);
        if (okHttpClient == null)
            okHttpClient = new OkHttpClient
                    .Builder()
//                    .sslSocketFactory(sslSocketFactory, trustManager)//此处就是添加证书
                    .readTimeout(60L, TimeUnit.SECONDS)
                    .connectTimeout(15L, TimeUnit.SECONDS)
                    .addInterceptor(loggingInterceptor)
                    .build();
        return okHttpClient;
    }

    private synchronized static void setOkHttpSsl(OkHttpClient.Builder okhttpBuilder) {
        try {
            // 自定义一个信任所有证书的TrustManager，添加SSLSocketFactory的时候要用到
            final X509TrustManager trustAllCert =
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[]{};
                        }
                    };
            final SSLSocketFactory sslSocketFactory = new SSLSocketFactoryCompat(trustAllCert);
            okhttpBuilder.sslSocketFactory(sslSocketFactory, trustAllCert);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static OkHttpClient upok() {
        loggingInterceptor.setLevel(level);
        if (okHttpClientyunup == null) {
            okHttpClientyunup = new OkHttpClient.Builder();
            setOkHttpSsl(okHttpClientyunup);
            okHttpClientyunup.readTimeout(60L, TimeUnit.SECONDS)
                    .connectTimeout(15L, TimeUnit.SECONDS)
                    .addInterceptor(loggingInterceptor);
        }
        return okHttpClientyunup.build();
    }

    static Retrofit yunRetrofit = null;
    static Retrofit yunUpRetrofit = null;

    protected static Retrofit getYunUpRetrofit() {
        if (yunUpRetrofit == null) {
            yunUpRetrofit = new Retrofit
                    .Builder()
                    .baseUrl(Constants.yunBaseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory.create())
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(upok())
                    .build();
        }
        return yunUpRetrofit;
    }

    protected static Retrofit getYunRetrofit() {
        if (yunRetrofit == null) {
            yunRetrofit = new Retrofit
                    .Builder()
                    .baseUrl(Constants.yunBaseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory.create())
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(ok())
                    .build();
        }
        return yunRetrofit;
    }

    protected static Retrofit getRetrofit() {
        if (mRetrofit == null) {
            mRetrofit = new Retrofit
                    .Builder()
                    .baseUrl(Constants.base_pos_url)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory.create())
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(ok())
                    .build();
        }
        return mRetrofit;
    }

    protected static Retrofit getRetrofitJQ() {
        if (mRetrofitJianQ == null) {
            mRetrofitJianQ = new Retrofit
                    .Builder()
                    .baseUrl(Constants.SYT_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory.create())
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(ok())
                    .build();
        }
        return mRetrofitJianQ;
    }

    protected static Retrofit getRetrofitNewJQ() {
        if (mRetrofitNewJQ == null) {
            mRetrofitNewJQ = new Retrofit
                    .Builder()
                    .baseUrl(Constants.AUTH_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory.create())
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(ok())
                    .build();
        }
        return mRetrofitNewJQ;
    }
    protected static Retrofit getQrRetrofit() {
        if (mRetrofitQR == null) {
            mRetrofitQR = new Retrofit
                    .Builder()
                    .baseUrl(Constants.base_pos_url)
                    .addCallAdapterFactory(retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory.create())
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(ok())
                    .build();
        }
        return mRetrofitQR;
    }
}
